#include <stdlib.h>
#include <iostream>

using std::cout;
using std::endl;


class Singleton
{
public:
    static Singleton * getInstance()
    {
        //多线程环境之下，同时有两个线程进入到if语句中
        //会造成内存泄漏, 创建多个对象，但只有一个对象的
        //地址会保存到_pInstance中
        //方法1： 加锁
        //方法2：
        if(_pInstance == nullptr) {
            _pInstance = new Singleton;
            //只有第一次调用getInstance函数时，会被调用
            atexit(destroy);
        }
        return _pInstance;
    }

    //方法三：如果destroy函数能在程序退出时自动调用，
    //也可以解决单例对象的自动释放
    static void destroy()
    {
        cout << "Singleton::destroy" << endl;
        if(_pInstance) {
            delete _pInstance;
            _pInstance = nullptr;
        }
    }

    void print() const
    {
        cout << "(" << _ix
             << "," << _iy
             << ")" << endl;
    }

    void init(int ix, int iy)
    {
        _ix = ix;
        _iy = iy;
    }

private:
    Singleton()
    : _ix(0), _iy(0)
    {   cout << "Singleton()" << endl;  }

    ~Singleton() {   cout << "~Singleton()" << endl;  }

private:
    static Singleton * _pInstance;
    int _ix;
    int _iy;
};

//静态数据成员要在类之外初始化
//Singleton * Singleton::_pInstance = nullptr;//懒加载(懒汉模式 -- 饱汉模式)
//初始化操作是在进入main函数之前做的
Singleton * Singleton::_pInstance = getInstance();//饿汉模式, 可以保证多线程安全


int main()
{
    Singleton * p1 = Singleton::getInstance();
    Singleton * p2 = Singleton::getInstance();
    cout << "p1: " << p1 << endl;
    cout << "p2: " << p2 << endl;
    Singleton::getInstance()->init(10, 11);//实际操作时的用法
    Singleton::getInstance()->print();
    cout << endl;

    return 0;
}

